<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数码测色计</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            overflow: hidden;
        }
        
        .container {
            display: flex;
            height: calc(100vh - 40px);
            gap: 20px;
        }
        
        .left-panel {
            flex: 1;
            display: flex;
            flex-direction: column;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 15px;
            padding: 20px;
            backdrop-filter: blur(10px);
        }
        
        .right-panel {
            width: 350px;
            display: flex;
            flex-direction: column;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 15px;
            padding: 20px;
            backdrop-filter: blur(10px);
        }
        
        h1 {
            font-size: 1.5em;
            margin-bottom: 20px;
            text-align: center;
        }
        
        .magnifier-container {
            flex: 1;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 10px;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            position: relative;
        }
        
        .magnifier {
            width: 300px;
            height: 300px;
            border: 2px solid rgba(255, 255, 255, 0.3);
            border-radius: 5px;
            background: #fff;
            image-rendering: pixelated;
            image-rendering: -moz-crisp-edges;
            image-rendering: crisp-edges;
            position: relative;
            overflow: hidden;
        }
        
        .magnifier canvas {
            width: 100%;
            height: 100%;
            display: block;
        }
        
        .crosshair {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 1px;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            pointer-events: none;
        }
        
        .crosshair::before {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            height: 1px;
            background: rgba(0, 0, 0, 0.8);
        }
        
        .crosshair::after {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 20px;
            height: 20px;
            border: 2px solid rgba(0, 0, 0, 0.8);
            border-radius: 50%;
            pointer-events: none;
        }
        
        .aperture-control {
            margin-top: 20px;
            width: 100%;
        }
        
        .aperture-label {
            display: flex;
            justify-content: space-between;
            margin-bottom: 10px;
            font-size: 0.9em;
        }
        
        .slider {
            width: 100%;
            height: 6px;
            border-radius: 3px;
            background: rgba(255, 255, 255, 0.2);
            outline: none;
            -webkit-appearance: none;
        }
        
        .slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: white;
            cursor: pointer;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        }
        
        .slider::-moz-range-thumb {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: white;
            cursor: pointer;
            border: none;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        }
        
        .color-info {
            margin-top: 20px;
        }
        
        .display-mode {
            margin-bottom: 20px;
        }
        
        .display-mode label {
            display: block;
            margin-bottom: 8px;
            font-size: 0.9em;
            opacity: 0.9;
        }
        
        .display-mode select {
            width: 100%;
            padding: 8px;
            border-radius: 5px;
            border: 1px solid rgba(255, 255, 255, 0.3);
            background: rgba(255, 255, 255, 0.1);
            color: white;
            font-size: 0.9em;
        }
        
        .display-mode select option {
            background: #667eea;
            color: white;
        }
        
        .color-swatch {
            width: 100%;
            height: 120px;
            border-radius: 10px;
            border: 2px solid rgba(255, 255, 255, 0.3);
            margin-bottom: 20px;
            background: #fff;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
        }
        
        .rgb-values {
            margin-bottom: 15px;
        }
        
        .rgb-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 5px;
            margin-bottom: 8px;
        }
        
        .rgb-label {
            font-weight: 600;
            font-size: 0.95em;
        }
        
        .rgb-value {
            font-family: 'Monaco', 'Courier New', monospace;
            font-size: 1.1em;
            font-weight: bold;
        }
        
        .hex-value {
            margin-top: 15px;
            padding: 12px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 5px;
            text-align: center;
        }
        
        .hex-label {
            font-size: 0.85em;
            opacity: 0.8;
            margin-bottom: 5px;
        }
        
        .hex-code {
            font-family: 'Monaco', 'Courier New', monospace;
            font-size: 1.3em;
            font-weight: bold;
            letter-spacing: 2px;
        }
        
        .color-profile {
            margin-top: 15px;
            padding: 10px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 5px;
            text-align: center;
            font-size: 0.9em;
            opacity: 0.8;
        }
        
        .controls {
            margin-top: 20px;
            display: flex;
            gap: 10px;
        }
        
        .btn {
            flex: 1;
            padding: 12px;
            border: none;
            border-radius: 8px;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            font-size: 0.9em;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .btn:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: translateY(-2px);
        }
        
        .btn-primary {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
        }
        
        .btn-primary:hover {
            background: linear-gradient(135deg, #f5576c 0%, #f093fb 100%);
        }
        
        .status {
            margin-top: 15px;
            padding: 10px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 5px;
            text-align: center;
            font-size: 0.85em;
            opacity: 0.8;
        }
        
        .pixel-info {
            margin-top: 10px;
            font-size: 0.85em;
            opacity: 0.7;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="left-panel">
            <h1>🔍 放大镜</h1>
            <div class="magnifier-container">
                <div class="magnifier" id="magnifier">
                    <canvas id="magnifierCanvas"></canvas>
                    <div class="crosshair"></div>
                </div>
                <div class="pixel-info" id="pixelInfo">移动鼠标到屏幕上拾取颜色</div>
            </div>
            <div class="aperture-control">
                <div class="aperture-label">
                    <span>光圈大小</span>
                    <span id="apertureValue">10x</span>
                </div>
                <input type="range" min="5" max="30" value="10" class="slider" id="apertureSlider">
            </div>
        </div>
        
        <div class="right-panel">
            <h1>📊 颜色信息</h1>
            <div class="display-mode">
                <label for="displayMode">显示原生值</label>
                <select id="displayMode">
                    <option value="sRGB">sRGB</option>
                    <option value="P3">Display P3</option>
                    <option value="AdobeRGB">Adobe RGB</option>
                </select>
            </div>
            
            <div class="color-swatch" id="colorSwatch"></div>
            
            <div class="rgb-values">
                <div class="rgb-item">
                    <span class="rgb-label">红 (Red)</span>
                    <span class="rgb-value" id="redValue">0</span>
                </div>
                <div class="rgb-item">
                    <span class="rgb-label">绿 (Green)</span>
                    <span class="rgb-value" id="greenValue">0</span>
                </div>
                <div class="rgb-item">
                    <span class="rgb-label">蓝 (Blue)</span>
                    <span class="rgb-value" id="blueValue">0</span>
                </div>
            </div>
            
            <div class="hex-value">
                <div class="hex-label">HEX</div>
                <div class="hex-code" id="hexValue">#000000</div>
            </div>
            
            <div class="color-profile" id="colorProfile">彩色 LCD</div>
            
            <div class="controls">
                <button class="btn btn-primary" id="startBtn">开始拾色</button>
                <button class="btn" id="stopBtn" disabled>停止拾色</button>
            </div>
            
            <div class="status" id="status">未启动</div>
        </div>
    </div>
    
    <script>
        const { ipcRenderer } = require('electron');
        
        let isCapturing = false;
        let apertureSize = 10;
        let currentColor = { r: 0, g: 0, b: 0 };
        let screenshotImage = null;
        let mouseX = 0;
        let mouseY = 0;
        let screenshotCache = null;
        let screenshotImageObj = null;
        let isProcessing = false;
        let pendingUpdate = null;
        
        // 创建隐藏的 canvas 用于处理截图
        const tempCanvas = document.createElement('canvas');
        const tempCtx = tempCanvas.getContext('2d');
        
        // 使用 requestAnimationFrame 优化渲染
        let animationFrameId = null;
        
        const magnifierCanvas = document.getElementById('magnifierCanvas');
        const magnifierCtx = magnifierCanvas.getContext('2d');
        const colorSwatch = document.getElementById('colorSwatch');
        const redValue = document.getElementById('redValue');
        const greenValue = document.getElementById('greenValue');
        const blueValue = document.getElementById('blueValue');
        const hexValue = document.getElementById('hexValue');
        const apertureSlider = document.getElementById('apertureSlider');
        const apertureValue = document.getElementById('apertureValue');
        const startBtn = document.getElementById('startBtn');
        const stopBtn = document.getElementById('stopBtn');
        const status = document.getElementById('status');
        const pixelInfo = document.getElementById('pixelInfo');
        
        // 设置画布大小
        magnifierCanvas.width = 300;
        magnifierCanvas.height = 300;
        
        // 光圈大小控制（优化：使用防抖）
        let apertureTimeout = null;
        apertureSlider.addEventListener('input', (e) => {
            apertureSize = parseInt(e.target.value);
            apertureValue.textContent = `${apertureSize}x`;
            
            // 如果正在拾色，立即更新放大镜
            if (isCapturing && screenshotImage && mouseX && mouseY) {
                // 清除之前的定时器
                if (apertureTimeout) {
                    clearTimeout(apertureTimeout);
                }
                
                // 防抖：延迟更新
                apertureTimeout = setTimeout(() => {
                    updateMagnifier({
                        screenshot: screenshotImage,
                        x: mouseX,
                        y: mouseY
                    });
                }, 50);
            }
        });
        
        // 开始拾色
        startBtn.addEventListener('click', () => {
            startColorPicking();
        });
        
        // 停止拾色
        stopBtn.addEventListener('click', () => {
            stopColorPicking();
        });
        
        function startColorPicking() {
            isCapturing = true;
            startBtn.disabled = true;
            stopBtn.disabled = false;
            status.textContent = '拾色中... 移动鼠标到屏幕上';
            
            // 请求主进程开始全局鼠标跟踪
            ipcRenderer.send('start-color-picking');
            
            // 监听鼠标位置和颜色（优化：使用节流）
            let lastUpdateTime = 0;
            const UPDATE_THROTTLE = 16; // 16ms，约60fps
            
            ipcRenderer.on('color-data', (event, data) => {
                if (!isCapturing) return;
                
                const now = performance.now();
                // 节流：确保不会过于频繁更新
                if (now - lastUpdateTime >= UPDATE_THROTTLE) {
                    lastUpdateTime = now;
                    updateMagnifier(data);
                } else {
                    // 保存最新的数据，等待下次更新
                    pendingUpdate = data;
                }
            });
        }
        
        function stopColorPicking() {
            isCapturing = false;
            startBtn.disabled = false;
            stopBtn.disabled = true;
            status.textContent = '已停止';
            
            // 取消动画帧
            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId);
                animationFrameId = null;
            }
            
            // 清空缓存
            screenshotCache = null;
            screenshotImageObj = null;
            pendingUpdate = null;
            isProcessing = false;
            
            // 请求主进程停止跟踪
            ipcRenderer.send('stop-color-picking');
            
            // 移除监听器
            ipcRenderer.removeAllListeners('color-data');
        }
        
        // 从截图中提取颜色（优化版本，使用缓存的图片对象）
        function extractColorFromScreenshot(screenshotDataUrl, x, y) {
            return new Promise((resolve) => {
                // 如果截图没有变化，使用缓存的图片对象
                if (screenshotCache === screenshotDataUrl && screenshotImageObj) {
                    extractColorFromImage(screenshotImageObj, x, y).then(resolve);
                    return;
                }
                
                // 新的截图，需要加载
                const img = new Image();
                img.onload = () => {
                    screenshotImageObj = img;
                    screenshotCache = screenshotDataUrl;
                    extractColorFromImage(img, x, y).then(resolve);
                };
                img.onerror = () => {
                    resolve({ r: 0, g: 0, b: 0 });
                };
                img.src = screenshotDataUrl;
            });
        }
        
        // 从已加载的图片对象中提取颜色
        function extractColorFromImage(img, x, y) {
            return new Promise((resolve) => {
                // 只在图片尺寸变化时重新设置画布
                if (tempCanvas.width !== img.width || tempCanvas.height !== img.height) {
                    tempCanvas.width = img.width;
                    tempCanvas.height = img.height;
                    tempCtx.drawImage(img, 0, 0);
                } else {
                    // 画布尺寸相同，直接使用（避免重复绘制）
                    // 但为了确保数据最新，还是需要重新绘制
                    tempCtx.drawImage(img, 0, 0);
                }
                
                // 获取鼠标位置的像素数据
                const imageData = tempCtx.getImageData(x, y, 1, 1);
                const pixel = imageData.data;
                
                // 返回 RGB 值
                resolve({
                    r: pixel[0],
                    g: pixel[1],
                    b: pixel[2]
                });
            });
        }
        
        function updateColorDisplay(data) {
            const { r, g, b, x, y } = data;
            currentColor = { r, g, b };
            mouseX = x;
            mouseY = y;
            
            // 更新颜色样本
            colorSwatch.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
            
            // 更新RGB值
            redValue.textContent = r;
            greenValue.textContent = g;
            blueValue.textContent = b;
            
            // 更新HEX值
            const hex = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`.toUpperCase();
            hexValue.textContent = hex;
            
            // 更新像素信息
            pixelInfo.textContent = `位置: (${x}, ${y})`;
        }
        
        // 优化的更新函数，使用防抖和缓存
        async function updateMagnifier(data) {
            if (!data || !data.screenshot) return;
            
            // 如果正在处理，保存最新的更新请求
            if (isProcessing) {
                pendingUpdate = data;
                return;
            }
            
            isProcessing = true;
            const { screenshot, x, y } = data;
            
            screenshotImage = screenshot;
            mouseX = x;
            mouseY = y;
            
            // 使用 requestAnimationFrame 优化渲染
            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId);
            }
            
            animationFrameId = requestAnimationFrame(async () => {
                try {
                    // 如果截图没有变化，使用缓存的图片对象
                    let img = screenshotImageObj;
                    
                    if (screenshotCache !== screenshot || !img) {
                        // 需要加载新图片
                        img = new Image();
                        await new Promise((resolve, reject) => {
                            img.onload = resolve;
                            img.onerror = reject;
                            img.src = screenshot;
                        });
                        screenshotImageObj = img;
                        screenshotCache = screenshot;
                    }
                    
                    // 计算放大区域
                    const scale = apertureSize;
                    const sourceSize = 300 / scale;
                    const sourceX = Math.max(0, x - sourceSize / 2);
                    const sourceY = Math.max(0, y - sourceSize / 2);
                    
                    // 使用图像平滑关闭，提升像素化效果
                    magnifierCtx.imageSmoothingEnabled = false;
                    
                    // 绘制放大后的图像
                    magnifierCtx.drawImage(
                        img,
                        sourceX, sourceY, sourceSize, sourceSize,
                        0, 0, 300, 300
                    );
                    
                    // 从截图中提取实际颜色
                    const color = await extractColorFromScreenshot(screenshot, x, y);
                    updateColorDisplay({
                        ...color,
                        x: x,
                        y: y
                    });
                } catch (error) {
                    console.error('更新放大镜失败:', error);
                } finally {
                    isProcessing = false;
                    
                    // 处理待处理的更新
                    if (pendingUpdate) {
                        const nextUpdate = pendingUpdate;
                        pendingUpdate = null;
                        updateMagnifier(nextUpdate);
                    }
                }
            });
        }
        
        // 窗口关闭时停止拾色
        window.addEventListener('beforeunload', () => {
            if (isCapturing) {
                stopColorPicking();
            }
        });
    </script>
</body>
</html>

